-
Notifications
You must be signed in to change notification settings - Fork 14k
Add ilog10 result range hints
#149207
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add ilog10 result range hints
#149207
Conversation
|
rustbot has assigned @Mark-Simulacrum. Use |
|
Is this motivated by concrete codegen improvements (the codegen tests are quite artificial)? |
|
Interesting that llvm can already infer some bounds, but apparently not the tightest ones. Looking at the following functions in compiler explorer, there are no panics: pub fn test_u8(i: std::num::NonZeroU8, a: &[u32; 3]) -> u32 {
a[i.ilog10() as usize]
}
pub fn test_u16(i: std::num::NonZeroU16, a: &[u32; 8]) -> u32 {
a[i.ilog10() as usize]
}
pub fn test_u32(i: std::num::NonZeroU32, a: &[u32; 13]) -> u32 {
a[i.ilog10() as usize]
}
pub fn test_u64(i: std::num::NonZeroU64, a: &[u32; 23]) -> u32 {
a[i.ilog10() as usize]
}These functions with tighter bounds would make for nicer codegen test. |
|
@Noratrieb: An example would be getting a slice of digits of an integer where adding an assertion can remove bound checking code: pub fn get_digits(mut x: u32, buffer: &mut [u8; 10]) -> &mut [u8] {
let digits = &mut buffer[..x.checked_ilog10().unwrap_or_default() as usize + 1];
for slot in &mut *digits {
*slot = (x % 10) as u8;
x /= 10;
}
digits
}You can compare the the codegen results here. Also, rust/library/core/src/num/uint_macros.rs Lines 3373 to 3392 in 94b49fd
I think it is reasonable that we do the same on |
This PR adds hints that the return value of
T::ilog10will never exceedT::MAX.ilog10().This works because
ilog10is a monotonically nondecreasing function, the maximum return value is reached at the max input value.